import sys
import logging
from pathlib import Path
from typing import Dict, Any
import structlog

from app.core.config import settings


def setup_logging():
    """设置日志配置"""

    # 确保日志目录存在
    log_dir = Path("logs")
    log_dir.mkdir(exist_ok=True)

    # 配置structlog
    structlog.configure(
        processors=[
            structlog.stdlib.filter_by_level,
            structlog.stdlib.add_logger_name,
            structlog.stdlib.add_log_level,
            structlog.stdlib.PositionalArgumentsFormatter(),
            structlog.processors.TimeStamper(fmt="iso"),
            structlog.processors.StackInfoRenderer(),
            structlog.processors.format_exc_info,
            structlog.processors.UnicodeDecoder(),
            structlog.processors.JSONRenderer()
        ],
        context_class=dict,
        logger_factory=structlog.stdlib.LoggerFactory(),
        wrapper_class=structlog.stdlib.BoundLogger,
        cache_logger_on_first_use=True,
    )

    # 配置标准库logging
    logging.basicConfig(
        format="%(message)s",
        stream=sys.stdout,
        level=getattr(logging, settings.LOG_LEVEL.upper()),
    )

    # 文件处理器
    file_handler = logging.FileHandler(settings.LOG_FILE, encoding="utf-8")
    file_handler.setLevel(getattr(logging, settings.LOG_LEVEL.upper()))

    # 设置文件日志格式
    file_formatter = logging.Formatter(
        "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    )
    file_handler.setFormatter(file_formatter)

    # 添加文件处理器到根日志记录器
    root_logger = logging.getLogger()
    root_logger.addHandler(file_handler)


def get_logger(name: str = None):
    """获取日志记录器"""
    return structlog.get_logger(name)


# 操作日志记录器
class OperationLogger:
    """操作日志记录器"""

    def __init__(self):
        self.logger = get_logger("operation")

    def log_operation(
        self,
        user_id: int,
        username: str,
        operation: str,
        resource: str,
        resource_id: str = None,
        result: str = "success",
        details: Dict[str, Any] = None,
        ip_address: str = None,
        user_agent: str = None,
    ):
        """记录操作日志"""
        log_data = {
            "user_id": user_id,
            "username": username,
            "operation": operation,
            "resource": resource,
            "resource_id": resource_id,
            "result": result,
            "details": details or {},
            "ip_address": ip_address,
            "user_agent": user_agent,
        }

        if result == "success":
            self.logger.info("Operation completed", **log_data)
        else:
            self.logger.warning("Operation failed", **log_data)

    def log_login(
        self,
        user_id: int,
        username: str,
        result: str = "success",
        ip_address: str = None,
        user_agent: str = None,
        error_message: str = None,
    ):
        """记录登录日志"""
        log_data = {
            "user_id": user_id,
            "username": username,
            "operation": "login",
            "result": result,
            "ip_address": ip_address,
            "user_agent": user_agent,
        }

        if error_message:
            log_data["error_message"] = error_message

        if result == "success":
            self.logger.info("User login", **log_data)
        else:
            self.logger.warning("Login failed", **log_data)

    def log_logout(
        self,
        user_id: int,
        username: str,
        ip_address: str = None,
    ):
        """记录登出日志"""
        log_data = {
            "user_id": user_id,
            "username": username,
            "operation": "logout",
            "result": "success",
            "ip_address": ip_address,
        }

        self.logger.info("User logout", **log_data)


# 创建操作日志记录器实例
operation_logger = OperationLogger()